package com.towexin.application.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.towexin.common.ResultData;
import com.towexin.config.mylogging.LogType;
import com.towexin.config.mylogging.MyLog;
import com.towexin.application.system.domain.User;
import com.towexin.application.system.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.Serializable;
import java.util.Deque;

/**
 * TODO
 *
 * @author 唐伟鑫
 * @version 1.0
 * @date 2021/4/8 11:57
 */
@RestController
@RequestMapping("user")
public class UserController {
	@Autowired
	private UserService service;

	@Autowired
	private EhCacheManager ehCacheManager;

	@MyLog(type = LogType.INSERT, operation = "增加新用户")
	@PostMapping("save")
	@RequiresPermissions("system.user.add")
	public ResultData saveOrUpdate(User user) {
		if (service.verificationUserName(user))
			return ResultData.NO("用户名已存在");

		return service.saveOrUpdateOne(user) ? ResultData.OK() : ResultData.NO("注册失败");
	}

	@MyLog(type = LogType.UPDATE, operation = "修改用户信息")
	@PostMapping("update")
	@RequiresPermissions("system.user.edit")
	public ResultData update(User user) {
		if (service.verificationUserName(user))
			return ResultData.NO("用户名已存在");

		if (service.getById(user.getId()).getUsername().equals(SecurityUtils.getSubject().getPrincipal())
				&& !user.getUsername().equals(SecurityUtils.getSubject().getPrincipal())) {
			SecurityUtils.getSubject().logout();
			return service.saveOrUpdateOne(user) ? ResultData.OK(201)
					: ResultData.NO("注册失败");
		}
		return service.saveOrUpdateOne(user) ? ResultData.OK() : ResultData.NO("注册失败");
	}

	@MyLog(type = LogType.DELETE, operation = "删除用户")
	@GetMapping("delete")
	@RequiresPermissions("system.user.delete")
	public ResultData deleteOne(String id) {
		return service.deleteOne(id) ? ResultData.OK() : ResultData.NO();
	}

	@MyLog(type = LogType.LOGIN, operation = "登录请求")
	@GetMapping("login")
	public ResultData login(String username, String password, boolean rememberMe) {
		return ResultData.OK(service.login(username, password, rememberMe), null);
	}

	@MyLog(type = LogType.UPDATE, operation = "为用户分配角色")
	@PostMapping("setRole")
	@RequiresPermissions("system.user.assignation")
	public ResultData setRole(String uId, String rId) {
		return service.setRole(uId, rId) ? ResultData.OK() : ResultData.NO();
	}

	@GetMapping("logout")
	public void logout() {
		Cache<String, Deque<Serializable>> cache = ehCacheManager.getCache("shiro-kick-out-session");
		cache.remove(SecurityUtils.getSubject().getPrincipal().toString());
		SecurityUtils.getSubject().logout();
	}

	//@MyLog(type = 1, operation = "获取用户列表")
	@GetMapping("selectPage")
	@RequiresPermissions("system.user.list")
	public ResultData selectUserPage(int page, int limit, String nickname) {
		if (nickname == null) {
			nickname = "";
		}
		return ResultData.OK(service.selectAndPage(page, limit, nickname));
	}

	@MyLog(type = LogType.UPDATE, operation = "更改用户状态")
	@GetMapping("changeStatus")
	@RequiresPermissions("system.user.status")
	public ResultData changeStatus(String userName, Boolean status) {
		if (userName == null || userName.equals("") || status == null)
			return ResultData.NO();
		return service.changeStatus(userName, status, 0) ? ResultData.OK() : ResultData.NO();
	}

	@GetMapping("online")
	public ResultData countOnline(){
		return ResultData.OK(String.valueOf(service.count(new QueryWrapper<User>().eq("online", Boolean.TRUE))));
	}

	@GetMapping("online-user")
	public ResultData getOnlineUsers(){
		return ResultData.OK(service.list(new QueryWrapper<User>().eq("online", Boolean.TRUE).select("username", "nickname")));
	}

}
